package com.parent.utils;

import org.apache.commons.collections4.CollectionUtils;

import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 类转化工具类
 *
 * @Author yan
 * @Date 2023/6/8 0008 10:38
 * @Description
 */
public class ClassToUtils {

    /**
     * map ==》T
     *
     * @param map
     * @param clazz 转化结果类 --返回类
     * @param <T>
     * @return T
     * @throws Exception
     */
    public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) throws Exception {
        T object = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            if (map.get(name) != null) {
                field.set(object, map.get(name));//设置属性值
            }
        }
        return object;
    }

    /**
     * keyName 替换
     *
     * @param map
     * @param replaceMapKeyName
     * @return
     */
    public static Map<String, Object> mapKeyNameReplace(Map<String, Object> map, Map<String, String> replaceMapKeyName) {
        Map<String, Object> mapNow = new LinkedHashMap<>();
        Set<String> keySet = replaceMapKeyName.keySet();
        keySet.stream().forEach(v -> {
            String value = replaceMapKeyName.get(v);
            Object o = map.get(v);
            mapNow.put(value, o);
        });
        return mapNow;
    }

    /**
     * Object ==》map
     *
     * @param o
     * @return Map<String, Object>
     * @throws Exception
     */
    public static Map<String, Object> objectToMap(Object o) throws Exception {
        Class<?> aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        Map<String, Object> map = new LinkedHashMap<>();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            Field fieldNow = aClass.getDeclaredField(name);
            fieldNow.setAccessible(true);
            Object value = fieldNow.get(o);// 获取属性值
            map.put(name, value);
        }
        return map;
    }

    /**
     * this object ==》 other object
     *
     * @param o
     * @param clazz
     * @param <T>
     * @return T
     * @throws Exception
     */
    public static <T> T objectToOtherObject(Object o, Class<T> clazz) throws Exception {
        Map<String, Object> map = objectToMap(o);
        T t = mapToObject(map, clazz);
        return t;
    }

    /**
     * @param o
     * @param clazz
     * @param <T>
     * @param replaceMapKeyName
     * @return T
     * @throws Exception
     */
    public static <T> T objectToOtherObjectKeyNameReplace(Object o, Class<T> clazz, Map<String, String> replaceMapKeyName) throws Exception {
        Map<String, Object> map = objectToMap(o);
        if (replaceMapKeyName != null) {
            map = mapKeyNameReplace(map, replaceMapKeyName);
        }
        T t = mapToObject(map, clazz);
        return t;
    }

    /**
     * list中所有的String类型 null 转化为 “”
     * @param list
     * @param appoints == null 全部
     * @throws Exception
     */
    public static void listStringAppointsSetNotNull(List<?> list, List<String> appoints) throws Exception {
        list.stream().forEach(v -> {
            try {
                objectStringAppointsSetNotNull(v,appoints);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * 类中所有的String类型 null 转化为 “”
     *
     * @param o
     * @throws Exception
     */
    public static void objectStringSetNotNull(Object o) throws Exception {
        Class<?> aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            Class<?> type = field.getType();
            // type 是 String 类型
            if (type.isAssignableFrom(String.class)) {
                Field fieldNow = aClass.getDeclaredField(name);
                fieldNow.setAccessible(true);
                Object value = fieldNow.get(o);// 获取属性值
                //value == null ==> ""
                if (value == null) {
                    field.set(o, "");//设置属性值
                }
            }
        }

    }

    /**
     * 类中指定名称的String类型 null 转化为 “”
     * @param o
     * @param appoints == null 全部
     * @throws Exception
     */
    public static void objectStringAppointsSetNotNull(Object o, List<String> appoints) throws Exception {
        Class<?> aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            if (CollectionUtils.isNotEmpty(appoints) && !appoints.contains(name)) {
                continue;
            }
            Class<?> type = field.getType();
            // type 是 String 类型
            if (type.isAssignableFrom(String.class)) {
                Field fieldNow = aClass.getDeclaredField(name);
                fieldNow.setAccessible(true);
                Object value = fieldNow.get(o);// 获取属性值
                //value == null ==> ""
                if (value == null) {
                    field.set(o, "");//设置属性值
                }
            }
        }

    }
}
